<template>
    <uv-upload :fileList="fileList" :width="width" :height="height" :maxSize="maxSize" :accept="accept" :uploadText="text"
        multiple :maxCount="limit" @afterRead="afterRead" @delete="deleteHandle" @beforeRead="beforeReadHandle"
        useBeforeRead>
        <slot></slot>
    </uv-upload>
</template>

<script setup lang="ts">
import { ref, defineProps, defineEmits, watch, getCurrentInstance } from 'vue'
import { convertToJson, computeFileExt } from '@/utils/index';
import { uploadFile, deleteFiles } from '@/services/platform'
const emit = defineEmits(['update:modelValue', 'change'])

const props = defineProps({
    modelValue: {
        type: [String, Array]
    },
    limit: {
        type: Number,
        default: 9
    },
    text: {
        type: String,
        default: '上传图片'
    },
    accept: {
        type: String,
        default: 'file'
    },
    maxSize: {
        type: Number,
        default: 30 * 1024 * 1024
    },
    customData: {
        type: Object
    },
    debug: {
        type: Boolean,
        default: false
    },
    allows: {
        type: Array,
    },
    width: {
        type: [Number, String],
        default: 80
    },
    height: {
        type: [Number, String],
        default: 80
    }
})

const fileList = ref([])

const initFiles = () => {

    if (props.modelValue && props.modelValue.length && typeof (props.modelValue) == 'object') {
        fileList.value = props.modelValue.map(p => {
            return {
                message: '',
                url: p,
                status: 'success' // uploading 上传中, success 成功, failed 失败
            }
        })
    }
    if (props.modelValue && typeof (props.modelValue) == 'string') {
        if (props.modelValue.startsWith('[')) {

            fileList.value = convertToJson(props.modelValue, 'array').map(p => {
                return {
                    message: '',
                    url: p,
                    status: 'success'
                }
            })

        } else {
            fileList.value = [{
                message: '',
                url: props.modelValue,
                status: 'success'
            }]
        }
    }
    if (!props.modelValue) {
        fileList.value = []
    }
}

watch(() => props.modelValue, () => {
    initFiles()
}, {
    deep: true,
    immediate: true
})

const beforeReadHandle = ({ file }) => {
    const needCheck = props.allows && props.allows.length
    const list = [].concat(file)
    for (let i = 0; i < list.length; i++) {
        if (needCheck && !props.allows.includes(computeFileExt(list[i].name).replace('.', ''))) {
            list[i].status = 'failed'
            list[i].message = '格式有误'
        } else {
            list[i].status = 'uploading'
            list[i].message = '上传中'
        }
    }
}

const afterRead = async ({ file }) => {
    let lists = [].concat(file)
    let fileListLen = fileList.value.length
    lists.map((item) => {
        fileList.value.push(item)
    })

    for (let i = 0; i < lists.length; i++) {
        if (lists[i].status == 'failed') {
            continue
        }
        let item = fileList.value[fileListLen]
        try {
            if (props.debug) {
                item.status = 'success'
                item.message = ''
                item.url = '/static/images/blank.png'
                updateFormValue()
                return
            }
            const data = await uploadFile(lists[i].url, props.customData)
            item.status = 'success'
            item.message = ''
            item.url = data[0].url
            updateFormValue()
        } catch (e) {
            item.status = 'failed'
            item.message = '上传失败'
        }
        fileListLen++
    }
}

const deleteHandle = ({ index }) => {
    const item = fileList.value[index]
    if (!props.debug && item.status == 'success') {
        deleteFiles([item.url]).then().catch(() => { })
    }
    fileList.value.splice(index, 1)
    updateFormValue()
}

const updateFormValue = () => {
    let formValue = null
    if (props.limit == 1) {
        formValue = fileList.value.filter(p => p.status == 'success')[0] ? fileList.value[0].url : ''
    } else {
        formValue = fileList.value.filter(p => p.status == 'success').map(p => p.url)
    }

    emit('update:modelValue', typeof (props.modelValue) == 'object' ? formValue : typeof (formValue) == 'object' ? JSON.stringify(formValue) : formValue)
    emit('change')

}
</script>

<style scoped></style>
